package Modules::LongORF;
use strict;
use Bio::SeqIO;

sub new {
  my ($class,$util) = @_;
  my $self = {
               util => $util,
             };
  bless $self,$class;
  return $self;
}

sub run {
  my $self        = shift;
  my $util        = $self->{'util'};
  my $source_path = $util->{'SOURCE_PATH'};
  my $data_path   = $util->{'DATA_PATH'};
  my $genome      = $data_path ."/". $util->{'GENOME'};
  my $fasta       = $data_path ."/". $util->{'GTF'} . ".fa"; 
  my $out;
  
  my ($sequenceformat,$notstrict,$graph,$printwidth,$help) 
    = ('fasta', undef, undef,50, undef);
    
  my $seqio = new Bio::SeqIO('-format' => $sequenceformat,
                             '-file' => $fasta );
  
  my ($length,$start,$end,$direction,$sequence);
  my $count=0;
  my @lengths;
  my $totallength=0;
  
  while (my $dna = $seqio->next_seq) {
    $count++;
    ($length,$start,$end,$direction,$sequence) = $self->longestORF($dna->seq,$notstrict);

    print ">".$dna->display_id," ",$dna->desc,": ";
    print "$length, $start, $end ($direction)\n$sequence\n\n";
     
    $totallength+=$length;
    $lengths[$length/3]++;
    my ($scaffold,$transcript_start,$transcript_end,$transcript_id) 
     = ($dna->desc =~ /(scaffold\w+):(\d+)-(\d+)\s+(\S+)$/);
    $out->{$transcript_id} = {
                              'id'               => $dna->display_id ,
                              'scaffold'         => $scaffold        ,
                              'transcript_start' => $transcript_start,
                              'transcript_end'   => $transcript_end  ,
                              'cds_start'        => $start           ,
                              'cds_end'          => $end             ,
                              'direction'        => $direction       ,
                             };
  last if $count ==3;

  }
  return $out;
}

sub longestORF {
   my ($self,$seq,$relaxed)      = @_;
   my ($bests,$beste,$beststrand)=(-1,-1,0);
   my $best    = 0;
   my $bestorf ="";

   my $dna=Bio::Seq->new(-seq => $seq);
   my %strand=('+'=>$dna->seq);

   foreach my $direction (keys %strand) {
      my @starts=();
      my @ends=();
      if ($relaxed) {
         for (my $frame=0;$frame<3;$frame++) {
            unless ($strand{$direction}=~m/^.{$frame}(taa|tga|tag)/i) {
               push @starts,$frame+1;
            }
         }
      }
      while ($strand{$direction}=~m/(atg)/gi) {
         push @starts,pos($strand{$direction})-2;
      }

      while ($strand{$direction}=~m/(taa|tga|tag)/gi) {
         push @ends,pos($strand{$direction})-2;
      }
      push @ends,($dna->length-2,$dna->length-1,$dna->length);

      for my $s (@starts) {
         for my $e (@ends) {
            if ($e%3==$s%3 and $e>$s) {
               if ($e-$s>$best) {
                  $best=$e-$s;
                  ($bests,$beste,$beststrand)=($s,$e,$direction);
                  $bestorf=Bio::Seq->new(-seq=>$strand{$direction})->subseq($s,$e);
               }
               last
            } else {
               next
            }
         }
      }
   }
   return ($best,$bests,$beste,$beststrand,$bestorf);
}
1;